package com.car.rental.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.car.rental.auth.entity.AuthUser;
import com.car.rental.auth.mapper.AuthUserMapper;
import com.car.rental.auth.model.request.LoginRequest;
import com.car.rental.auth.model.request.RegisterRequest;
import com.car.rental.auth.model.response.LoginResponse;
import com.car.rental.auth.service.AuthService;
import com.car.rental.common.core.exception.BusinessException;
import com.car.rental.common.core.response.ResponseResult;
import com.car.rental.common.utils.JwtUtils;

import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.car.rental.auth.utils.RedisUtil;
import org.springframework.util.StringUtils;
import com.car.rental.auth.entity.UserRole;
import com.car.rental.auth.mapper.UserRoleMapper;

@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final AuthUserMapper authUserMapper;
    private final UserRoleMapper userRoleMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtils jwtUtil;
    private final RedisUtil redisUtil;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> register(RegisterRequest registerRequest) {
        // 1. 验证密码
        if (!registerRequest.getPassword().equals(registerRequest.getConfirmPassword())) {
            return ResponseResult.error("两次输入的密码不一致");
        }

        // 2. 检查用户名是否已存在
        if (authUserMapper.selectOne(new LambdaQueryWrapper<AuthUser>()
                .eq(AuthUser::getUsername, registerRequest.getUsername())) != null) {
            return ResponseResult.error("用户名已存在");
        }

        // 3. 创建用户
        AuthUser user = new AuthUser();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setStatus(1);  // 1-正常

        // 设置角色和nickname
        Long roleId = 3L;  // 默认普通用户
        String roleName = "普通用户";
        if (roleId.equals(1L)) {
            roleName = "超级管理员";
        } else if (roleId.equals(2L)) {
            roleName = "管理员";
        } else if (roleId.equals(4L)) {
            roleName = "商家";
        }
        user.setNickname(roleName);  // 设置nickname为角色名称
        
        authUserMapper.insert(user);

        // 关联角色
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);

        return ResponseResult.success();
    }
    
    @Override
    public ResponseResult<LoginResponse> login(LoginRequest loginRequest) {
        // 1. 查询用户
        AuthUser user = getUserByUsername(loginRequest.getUsername());
        if (user == null) {
            throw new BusinessException("用户名或密码错误");
        }
        
        // 2. 验证密码
        if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }
        
        // 3. 检查用户状态
        if (user.getStatus() != 1) {
            throw new BusinessException("账号已被禁用");
        }
        
        // 4. 生成token
        String token = generateToken(user);
        
        // 5. 构建响应
        LoginResponse response = LoginResponse.builder()
                .token(token)
                .userId(user.getId())
                .username(user.getUsername())
                .build();
        
        return ResponseResult.success(response);
    }
    
    @Override
    public ResponseResult<Void> logout(String token) {
        if (StringUtils.hasText(token)) {
            // 如果token以"Bearer "开头，需要去掉这个前缀
            if (token.startsWith("Bearer ")) {
                token = token.substring(7);
            }

            // 获取token的过期时间
            long expiration = jwtUtil.getExpirationFromToken(token);
            long currentTime = System.currentTimeMillis() / 1000;
            long remainingTime = expiration - currentTime;
            
            // 如果token还未过期，加入黑名单
            if (remainingTime > 0) {
                redisUtil.addToBlacklist(token, remainingTime);
            }
        }
        return ResponseResult.success();
    }
    
    @Override
    public ResponseResult<Boolean> validateToken(String token) {
        // 1. 验证token格式
        if (!StringUtils.hasText(token)) {
            throw new BusinessException("token不能为空");
        }

        // 2. 验证token有效性
        if (!jwtUtil.validateToken(token)) {
            throw new BusinessException("token已过期或无效");
        }

        // 3. 检查token是否在黑名单中
        if (redisUtil.isInBlacklist(token)) {
            throw new BusinessException("token已失效");
        }

        return ResponseResult.success(true);
    }
    
    @Override
    public ResponseResult<LoginResponse> getUserInfo(String token) {
        // 如果token以"Bearer "开头，需要去掉这个前缀
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }

        if (!jwtUtil.validateToken(token)) {
            throw new BusinessException("token已过期或无效");
        }
        
        Long userId = jwtUtil.getUserIdFromToken(token);
        
        // 获取用户信息
        AuthUser user = authUserMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 获取用户角色
        UserRole userRole = userRoleMapper.selectOne(
            new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId)
        );
        String roleName = "普通用户";
        if (userRole != null) {
            Long roleId = userRole.getRoleId();
            if (roleId.equals(1L)) {
                roleName = "超级管理员";
            } else if (roleId.equals(2L)) {
                roleName = "管理员";
            } else if (roleId.equals(4L)) {
                roleName = "商家";
            }
        }
        
        LoginResponse response = LoginResponse.builder()
                .token(token)
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .avatar(user.getAvatar())
                .status(user.getStatus())
                .role(roleName)
                .createTime(user.getCreateTime())
                .build();
        
        return ResponseResult.success(response);
    }
    
    private AuthUser getUserByUsername(String username) {
        LambdaQueryWrapper<AuthUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AuthUser::getUsername, username);
        return authUserMapper.selectOne(wrapper);
    }
    
    private String generateToken(AuthUser user) {
        return jwtUtil.generateToken(user.getId(), user.getUsername());
    }
} 